#!/usr/bin/env python3
# -*- coding:utf-8 -*-
#
# Copyright 2021 Shanghai Lightning Semiconductor Technology Co., LTD

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import json
import os
import sys
import argparse
from ln_tools import check_python_version


class BeforeBuildBase:
    DEFAULT_FLASH_TABLE_NAME = "flash_partition_table.h"
    ALIGN = "32"
    IMAGE_HEADER_SIZE_STR = "0x100"

    def __init__(self) -> None:
        # absolute filepath of flash_partition_cfg.json
        self.partcfg_filepath   = None
        # absolute filepath of flash_partition_table.h
        self.headfile_filepath  = None

    def prepare(self, *args):
        # Depends on IDE.
        return True

    def build_stage_first(self) -> bool:
        result = dict()

        try:
            if (sys.version_info.major >= 3):
                with open(self.partcfg_filepath, 'r', encoding='utf-8') as f:
                    result = json.loads(f.read())
            else:
                with open(self.partcfg_filepath, 'r') as f:
                    result = json.loads(f.read())
        except Exception as err:
            print("Error: load json file failed: {}".format(str(err)))
            return False

        with open(self.headfile_filepath, "w+") as f:
            filepath, wfile_path = os.path.split(self.headfile_filepath)
            file_v = wfile_path.replace(".h","").upper()
            startcomment = "#ifndef __" + file_v + "__\n#define __" + file_v + "__\n\n\n//flash partition map,it's generated by the script based on the json file <flash_partition_table.json>\n"
            f.writelines(startcomment)

            count = 0
            last_name1 = ""
            last_name2 = ""
            value = []
            for i in result["vendor_define"]:
                value.append(i)
            for i in result["user_define"]:
                value.append(i)
            try:
                for i in value:
                    name1 = i['partition_type'] + "_SPACE_OFFSET"
                    name2 = i['partition_type'] + "_SPACE_SIZE"

                    temp1 = "".join(["#define ",  format(name1," <"+ BeforeBuildBase.ALIGN),  " (",  i['start_addr'],  ")"])
                    temp2 = "".join(["#define ",  format(name2," <"+ BeforeBuildBase.ALIGN),  " (1024*",  str(i['size_KB']),  ')'])

                    f.writelines("\n"+temp1+"\n")
                    f.writelines(temp2+"\n")

                    if (count > 0):
                        temp3 = "".join(["#if (", name1, " < (", last_name1, " + ", last_name2, "))"])
                        f.writelines(temp3 + "\n")
                        f.writelines("  #error \"flash partition overlap,please check <flash_partition_table.json>!!!\"\n")
                        f.writelines("#endif\n")

                    count = count + 1
                    last_name1 = name1
                    last_name2 = name2
            except Exception as e:
                print(e)

            temp = "".join(["\n\n#define ",  format("IMAGE_HEADER_SIZE"," <"+ BeforeBuildBase.ALIGN),  " ",  "("+ BeforeBuildBase.IMAGE_HEADER_SIZE_STR+")"])
            f.writelines(temp)
            endcommont = "\n\n#endif /* __" + file_v + "__ */\n\n"
            f.writelines(endcommont)

        print("Succeed to build: {}".format(self.headfile_filepath))
        return True

    def build_stage_second(self) -> bool:
        return True

    def build_stage_third(self) -> bool:
        return True

    def doAllWork(self) -> bool:
        if not self.build_stage_first():
            return False

        if not self.build_stage_second():
            return False

        if not self.build_stage_third():
            return False
        return True


if __name__ == "__main__":
    check_python_version()

    prog = os.path.basename(__file__)
    desc = "Before Build Action"
    parser = argparse.ArgumentParser(prog=prog, description=desc)
    parser.add_argument("-p", "--partcfg",  help="filepath of flash partition config", type=str)
    parser.add_argument("-o", "--output",   help="filepath of flash_partition_table.h", type=str)
    args = parser.parse_args()

    if not args.partcfg:
        print("Error: flash partition config file (flash_partition_cfg.json) has not been set!!!")
        exit(-1)

    if not args.output:
        print("Error: flash partition table filepaht has not been set!!!")
        exit(-2)

    buildObj = BeforeBuildBase()
    if not buildObj.prepare(args.partcfg, args.output):
        exit(-11)

    if not buildObj.doAllWork():
        exit(-12)

    exit(0)
